home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_2 / ispell-3.3ljr / ispell / icombine.c < prev    next >
C/C++ Source or Header  |  1992-09-22  |  6KB  |  229 lines

  1. /*
  2.    icombine:  combine multiple ispell dictionary entries into a single
  3.               entry with the options of all entries
  4.  
  5.    Author:  Gary Puckering
  6.             Cognos, Inc.
  7.  
  8.    Written:  January 29, 1987
  9.  
  10.    Notes:  Input lines consist of a word followed optionally by
  11.            by one or more flags.  e.g CREATE/V/N/S
  12.  
  13.            Flags on lines with identical root words are combined.
  14.            No editing on flags is performed.
  15.            Flags are forced to uppercase, but roots are left alone.
  16.            Old-style flags, like /X/N will be output as /NX.
  17.            Flags are output in alphabetical order.
  18.            Non-letters appearing before the first "/" are retained,
  19.              those after are dropped.
  20.            Root words that differ only in capitalization are combined.
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <ctype.h>
  25. #include <string.h>
  26. #include "config.h"
  27. #include "ispell.h"
  28.  
  29. void putword (void);
  30. void parse (char ln[], char wrd[], char flgs[]);
  31. void getflags (char *flgs);
  32. void putflags (void);
  33. int resolvecaps (char *word, char *ucword, char *lastword, char *uclastword);
  34. void uccopy (char *dest, char *src);
  35.  
  36. #define MAXFLAGS 26        /* letters A-Z */
  37. #define MAXLINE 255        /* maximum line size */
  38.  
  39. #define TRUE 1
  40. #define FALSE 0
  41. typedef int bool;
  42.  
  43. bool flagtbl[MAXFLAGS];        /* array of flag options */
  44.  
  45. char line[MAXLINE];        /* current line */
  46. char lastword[MAXLINE];        /* previous word */
  47. char uclastword[MAXLINE];    /* uppercase version of lastword */
  48. char word[MAXLINE];        /* current word */
  49. char ucword[MAXLINE];        /* uppercase version of current word */
  50. char flags[MAXLINE];        /* current flags */
  51. int expand = 0;            /* if NZ, expand instead of combining */
  52.  
  53. void main (int argc, char *argv[])
  54. {
  55.  
  56.   if (argc > 1 && strcmp (argv[1], "-e") == 0)
  57.     expand = 1;
  58.   if (gets (line))
  59.     {
  60.       parse (line, lastword, flags);
  61.       uccopy (uclastword, lastword);
  62.       getflags (flags);
  63.     }
  64.   else
  65.     return;
  66.  
  67.   while (gets (line))
  68.     {
  69.       parse (line, word, flags);
  70.       uccopy (ucword, word);
  71.       if (strcmp (word, lastword) != 0)    /* possibly different word */
  72.     {
  73.       if (strcmp (ucword, uclastword) != 0    /* truly different word */
  74.           || resolvecaps (word, ucword, lastword, uclastword))
  75.         {            /* or caps differ */
  76.           putword ();
  77.           strcpy (lastword, word);
  78.           strcpy (uclastword, ucword);
  79.         }
  80.     }
  81.       getflags (flags);
  82.     }
  83.   putword ();
  84.   return;
  85. }
  86.  
  87. void putword (void)
  88. {
  89.   printf ("%s", lastword);
  90.   putflags ();
  91. }
  92.  
  93. void parse (char ln[], char wrd[], char flgs[])
  94. {
  95.   register char *p, *q;
  96.  
  97.   /* copy line up to first "/" or to end */
  98.   for (p = ln, q = wrd; *p && *p != '/'; p++, q++)
  99.     *q = *p;
  100.   *q = NULL;
  101.  
  102.   strcpy (flgs, p);        /* copy from "/" to end */
  103. }
  104.  
  105. void getflags (char *flgs)
  106. {
  107.   register char *p;
  108.  
  109.   for (p = flgs; *p; p++)
  110.     if (*p != '/')
  111.       {
  112.     if (islower (*p))
  113.       *p = toupper (*p);
  114.     if (isupper (*p))
  115.       flagtbl[(*p) - 'A'] = TRUE;
  116.       }
  117. }
  118.  
  119. void putflags (void)
  120. {
  121.   register int i;
  122.   int slashout = 0;
  123.  
  124.   if (expand)
  125.     putchar ('\n');
  126.  
  127.   for (i = 0; i < MAXFLAGS; i++)
  128.     if (flagtbl[i])
  129.       {
  130.     if (expand)
  131.       printf ("%s/%c\n", lastword, i + 'A');
  132.     else
  133.       {
  134.         if (!slashout)
  135.           putchar ('/');
  136.         slashout = 1;
  137.         putchar (i + 'A');
  138.       }
  139.     flagtbl[i] = FALSE;
  140.       }
  141.   if (!expand)
  142.     putchar ('\n');
  143. }
  144.  
  145. /*
  146.  * This routine resolves capitalization conflicts.  The idea is to combine
  147.  * only those cases that ispell can "uncombine".
  148.  *
  149.  * Entry: word and lastword differ, but only by case.
  150.  *
  151.  * Exit: Returns 1 if word and lastword both need to be in the dictionary,
  152.  *     0 if they can be handled by a single entry.  If the return is zero,
  153.  *     lastword may have been modified to reflect the union of the two
  154.  *     entries.
  155.  *
  156.  * Rules:
  157.  *
  158.  * (1) If either word is entirely in upper case, it "loses" to the other
  159.  *     word.  The "winning" word is copied to lastword, and 0 is returned.
  160.  * (2) If either word is "followcase" (defined as being mixed case with a
  161.  *     capital letter appearing after the first character), the two
  162.  *     variants are considered to differ, and 1 is returned.  Furthermore,
  163.  *     a flag is set (by copying the word to "lastfollow") so that all
  164.  *     future variants fo the word will be considered to differ.
  165.  * (3) If one word is capitalized and the other is all-lowercase, the
  166.  *     lowercase word "wins".  It is copied to lastword, and 0 is returned.
  167.  *     HOWEVER, if a "followcase" variant of the word has been seen, this
  168.  *     rule does not apply, and rule (4) will cause the words to be
  169.  *     considered different.
  170.  * (4) If a "followcase" variant of the word has been seen, the words are
  171.  *     always considered to differ.  1 is returned.
  172.  *
  173.  * Note that the input must be sorted with "sort -t/ +0f -1 +0 -1" for this
  174.  * code to work.
  175.  */
  176. int resolvecaps (char *word, char *ucword, char *lastword, char *uclastword)
  177. {
  178.   register char *w;
  179.   register char *lw;
  180.   static char lastfollow[200] = "";
  181.  
  182.   /* Rule (1): Upper case loses */
  183.   for (w = word; *w && !mylower (*w); w++)
  184.     ;
  185.   if (*w == '\0')
  186.     return 0;
  187.   for (lw = lastword; *lw && !mylower (*lw); lw++)
  188.     ;
  189.   if (*lw == '\0')
  190.     {
  191.       strcpy (lastword, word);
  192.       strcpy (uclastword, ucword);
  193.       return 0;
  194.     }
  195.   /* Rule (4):  followcase forces all subsequent variants to be different. */
  196.   if (strcmp (ucword, lastfollow) == 0)
  197.     return 1;
  198.   /* Rule (2):  "followcase" is different. */
  199.   for (w = word + 1, lw = lastword + 1;
  200.        *w && !myupper (*w) && !myupper (*lw);
  201.        w++, lw++)
  202.     ;
  203.   if (*w)            /* We don't test *lw 'cause lengths are the same */
  204.     {
  205.       strcpy (lastfollow, ucword);
  206.       return 1;
  207.     }
  208.   /* Rule (3):  all-lowercase beats capitalized */
  209.   if (myupper (lastword[0]))
  210.     {
  211.       strcpy (lastword, word);
  212.       strcpy (uclastword, ucword);
  213.     }
  214.   return 0;
  215. }
  216.  
  217. void uccopy (char *dest, char *src)
  218. {
  219.   while (*src)
  220.     {
  221.       if (mylower (*src))
  222.     *dest++ = toupper (*src);
  223.       else
  224.     *dest++ = *src;
  225.       src++;
  226.     }
  227.   *dest = '\0';
  228. }
  229.